 package implementation.gambiarra;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import entility.Job;
import entility.JobImpl;
import entility.Machine;
import entility.Notification;

public class Client implements Runnable{

	private Machine mainServer;
	private List<Machine> servers;
	private List<Machine> hosts;
	private String path;


	public Client(String serverIp, int serverPort, String path) throws Exception {
		
		
		mainServer = new Machine(serverIp, serverPort);
		hosts = new ArrayList<Machine>();
		this.path = path;

		//hosts
		Job j = new JobImpl(Notification.CLIENT);
		j.setMethod("getHosts");
		List<String> listHosts = mainServer.getMessage(j).getData();

		System.out.println("Estao cadastrados : "+listHosts.size()+ " hosts");

		for(String r : listHosts){
			String host[] = r.split(":");
			Machine newHost = new Machine(host[0], Integer.parseInt(host[1]));
			hosts.add(newHost);
		}

		//servers
		j.setMethod("getServers");
		List<String> listServers = mainServer.getMessage(j).getData();

		servers = new ArrayList<Machine>();
		for(String r : listServers){

			String server[] = r.split(":");
			if(!server[0].equals(mainServer.ip))
			{
				Machine newServer = new Machine(server[0], Integer.parseInt(server[1]));
				servers.add(newServer);
			}
		}
		


	}


	public Machine getMainServer() {
		return mainServer;
	}
	public void setMainServer(Machine mainServer) {
		this.mainServer = mainServer;
	}

	public List<Machine> getServers() {
		return servers;
	}
	public void setServers(List<Machine> servers) {
		this.servers = servers;
	}

	public List<Machine> getHosts() {
		return hosts;
	}
	public void setHosts(List<Machine> hosts) {
		this.hosts = hosts;
	}

	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}

	


	public void sendJobs(String path) {

		File folder = new File(path);

		int k = -1;
		List<File> arqs = new ArrayList<File>();

		System.out.println(folder);
		
		Thread controller = ClientController.getInstance();
		controller.start();

		for(File file : folder.listFiles()) {
			arqs.add(file);
		}

		//FileComparator ord = new FileComparator();
		//Collections.sort(arqs, ord);



		/*try {*/
		Machine host = null;
		for(File file : arqs) {
			try{

				k++;
				host = getHosts().get(k % getHosts().size());
				//SendFiles s = new SendFiles(host, file);
				//s.sendFiles();
				Job job = new JobImpl(Notification.CLIENT);
				job.setData(host);
				List<String> data = job.getData();
				data.add(file.getAbsolutePath());
				
				job.setData(data);
				
				ClientController control = ClientController.getInstance();
				control.add(job);

				//Thread t = new Thread(s);
				//t.start();
				if(k%100 == 50 )
				{
					System.out.println("File: "+k);
					
				}

			}
			//Falha ao connectar com o Host
			catch(Exception e)
			{
				e.printStackTrace();
				System.out.println("Notification Host : " + file.getName());
				Notification serverFail = new  Notification();

				Notification notify = new Notification();
				notify.setMachine(host);
				notify.setMessage(Notification.MESSAGEERROR);
				notify.setType(Notification.HOST);

				Job notifyFailHost = new JobImpl(Notification.CLIENT);
				notifyFailHost.setMethod("notify");
				notifyFailHost.setData(notify.getJobData());

				try{


					mainServer.getMessage(notifyFailHost,2000);
					Job getHosts = new JobImpl(Notification.CLIENT);
					getHosts.setMethod("getHosts");
					mainServer.getMessage(getHosts, 2000);

				}
				catch(Exception e2)
				{

					System.out.println("Notifification server");
					serverFail.setMachine(mainServer);
					serverFail.setMessage(Notification.MESSAGEERROR);
					serverFail.setType(Notification.SERVER);
					Job sFail = new JobImpl(Notification.CLIENT);
					sFail.setData(serverFail.getJobData());
					sFail.setMethod("notify");

					if(getIndex(mainServer) != -1)
						servers.remove(getIndex(mainServer));


					if(servers.size() > 0 )
					{
						mainServer = servers.get(0);
						try{


							mainServer.getMessage(sFail);
							mainServer.getMessage(notifyFailHost);

						}catch(Exception e3){

							System.out.println("Sem servidores disponiveis fails");
							System.exit(0);

						}


					}
					else
					{
						System.out.println("Sem servidores disponiveis");
						System.exit(0);
					}
				}


				Main.start(mainServer.ip, mainServer.port);



			}
		}
		System.out.println("Arquivos enviados!");
		
	}

	private int getIndex(Machine mainServer2) {


		for(int i = 0; i< servers.size(); i++)
		{
			if(servers.get(i).ip.equals(mainServer2.ip))
				return i;

		}
		return -1;

	}


	@Override
	public void run() throws RuntimeException{
		sendJobs(path);
		
	}
}
